﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKRevitCode.RevitObjectCompareUtility;
using YJKRGeometry;

namespace YJKArchMethodLibrary.StructurePoleSuit
{
	public class BaseColumnLoopSearcher : StructureLoopSearcher
	{
		public BaseColumnLoopSearcher(ExternalCommandData commandData, bool isSearchEdgeLoops, XYZ selecetBoxMin = null, XYZ selecetBoxMax = null, Dictionary<XYZ, bool> pointTag = null) : base(commandData, isSearchEdgeLoops)
		{
			this.m_SelecetBoxMin = selecetBoxMin;
			this.m_SelecetBoxMax = selecetBoxMax;
			this.m_dicUsePointTag = pointTag;
			if (this.m_dicUsePointTag != null)
			{
				Dictionary<XYZ, bool> dicUsePointTag = this.m_dicUsePointTag;
				this.m_dicUsePointTag = new Dictionary<XYZ, bool>(new XYZEqualityComparer());
				foreach (KeyValuePair<XYZ, bool> keyValuePair in dicUsePointTag)
				{
					this.m_dicUsePointTag.Add(keyValuePair.Key, keyValuePair.Value);
				}
			}
		}

		protected bool IsPointMove(XYZ pt)
		{
			if ((this.m_SelecetBoxMax == null || this.m_SelecetBoxMin == null) && (this.m_dicUsePointTag == null || this.m_dicUsePointTag.Count == 0))
			{
				return false;
			}
			if (this.m_dicUsePointTag != null && this.m_dicUsePointTag.ContainsKey(pt))
			{
				return this.m_dicUsePointTag[pt];
			}
			return this.m_SelecetBoxMax != null && this.m_SelecetBoxMin != null && !Geometry.LessThan(pt.X, this.m_SelecetBoxMin.X) && !Geometry.LessThan(this.m_SelecetBoxMax.X, pt.X) && !Geometry.LessThan(pt.Y, this.m_SelecetBoxMin.Y) && !Geometry.LessThan(this.m_SelecetBoxMax.Y, pt.Y);
		}

		protected Curve GetCurve(XYZ ptStart, XYZ ptEnd, double bugle)
		{
			Curve result;
			try
			{
				Curve curve;
				if (Geometry.IsEqual(bugle, 0.0))
				{
					curve = YJKLineEx.YJKGetBound(ptStart, ptEnd);
				}
				else
				{
					XYZ ptCenter = null;
					Geometry.GetCenterWithBulge(ptStart, ptEnd, bugle, ref ptCenter);
					XYZ radianPnt = Geometry.CalculatMidPoint(ptStart, ptEnd, ptCenter, XYZ.BasisZ);
					curve = this.m_Revit.Application.Application.CreatYJKArc(ptStart, ptEnd, radianPnt);
				}
				result = curve;
			}
			catch (Exception)
			{
				result = null;
			}
			return result;
		}

		protected void FindLinkedNodes(List<Structure2DNode> allSet, Structure2DNode currentNode, ref List<Structure2DNode> selectSet)
		{
			XYZ position = currentNode.Position;
			foreach (Structure2DPole structure2DPole in currentNode.PoleList)
			{
				Structure2DNode findNode = base.FindNodeByPos(allSet, structure2DPole.CurOutNodePosition(position));
				if (findNode != null)
				{
					int num = selectSet.FindIndex((Structure2DNode s) => s.Position.Equals(findNode.Position));
					if (num == -1)
					{
						selectSet.Add(findNode);
						this.FindLinkedNodes(allSet, findNode, ref selectSet);
					}
				}
			}
		}

		protected void GetProfileCurves(List<Structure2DNode> nodes, ref List<List<Curve>> profileEdgeLoop)
		{
			List<Structure2DNode> list = new List<Structure2DNode>();
			list.AddRange(nodes);
			List<List<Structure2DNode>> list2 = new List<List<Structure2DNode>>();
			while (list.Count > 0)
			{
				Structure2DNode structure2DNode = list[0];
				List<Structure2DNode> list3 = new List<Structure2DNode>();
				list3.Add(structure2DNode);
				this.FindLinkedNodes(list, structure2DNode, ref list3);
				list2.Add(list3);
				using (List<Structure2DNode>.Enumerator enumerator = list3.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						Structure2DNode node = enumerator.Current;
						int num = list.FindIndex((Structure2DNode s) => s.Position.Equals(node.Position));
						if (num != -1)
						{
							list.RemoveAt(num);
						}
					}
				}
			}
			List<Curve> list4 = new List<Curve>();
			foreach (List<Structure2DNode> list5 in list2)
			{
				List<Curve> collection = new List<Curve>();
				List<ColumnProfilePart> currentAllPartList = this.GetCurrentAllPartList(list5);
				foreach (ColumnProfilePart columnProfilePart in currentAllPartList)
				{
					XYZ startPoint = columnProfilePart.StartPoint;
					XYZ endPoint = columnProfilePart.EndPoint;
					if (columnProfilePart.IsValidSideLineOfPositive() == Structure2DPole._tagSideLineValidType._Valide)
					{
						this.AddCurveToProfile(columnProfilePart.PositiveStartPoint, columnProfilePart.PositiveEndPoint, columnProfilePart.Bulge, ref collection);
					}
					if (columnProfilePart.IsValidSideLineOfNegative() == Structure2DPole._tagSideLineValidType._Valide)
					{
						this.AddCurveToProfile(columnProfilePart.NegativeStartPoint, columnProfilePart.NegativeEndPoint, columnProfilePart.Bulge, ref collection);
					}
					Structure2DNode structure2DNode2 = base.FindNodeByPos(list5, startPoint);
					if (structure2DNode2 != null && structure2DNode2.PoleList.Count == 1)
					{
						XYZ ptStart = columnProfilePart.CurPositiveStartPoint(structure2DNode2.Position);
						XYZ ptEnd = columnProfilePart.CurNegativeStartPoint(structure2DNode2.Position);
						this.AddCurveToProfile(ptStart, ptEnd, 0.0, ref collection);
					}
					Structure2DNode structure2DNode3 = base.FindNodeByPos(list5, endPoint);
					if (structure2DNode3 != null && structure2DNode3.PoleList.Count == 1)
					{
						XYZ ptStart2 = columnProfilePart.CurPositiveStartPoint(structure2DNode3.Position);
						XYZ ptEnd2 = columnProfilePart.CurNegativeStartPoint(structure2DNode3.Position);
						this.AddCurveToProfile(ptStart2, ptEnd2, 0.0, ref collection);
					}
					if (columnProfilePart.VariableCross_SectionInPositiveStart != null)
					{
						this.AddCurveToProfile(columnProfilePart.VariableCross_SectionInPositiveStart.StartPoint, columnProfilePart.VariableCross_SectionInPositiveStart.EndPoint, 0.0, ref collection);
					}
					if (columnProfilePart.VariableCross_SectionInPositiveEnd != null)
					{
						this.AddCurveToProfile(columnProfilePart.VariableCross_SectionInPositiveEnd.StartPoint, columnProfilePart.VariableCross_SectionInPositiveEnd.EndPoint, 0.0, ref collection);
					}
					if (columnProfilePart.VariableCross_SectionInNegativeStart != null)
					{
						this.AddCurveToProfile(columnProfilePart.VariableCross_SectionInNegativeStart.StartPoint, columnProfilePart.VariableCross_SectionInNegativeStart.EndPoint, 0.0, ref collection);
					}
					if (columnProfilePart.VariableCross_SectionInNegativeEnd != null)
					{
						this.AddCurveToProfile(columnProfilePart.VariableCross_SectionInNegativeEnd.StartPoint, columnProfilePart.VariableCross_SectionInNegativeEnd.EndPoint, 0.0, ref collection);
					}
				}
				list4.AddRange(collection);
			}
			profileEdgeLoop = base.GetFullFloorEdgeLoops(list4);
		}

		protected List<ColumnProfilePart> GetCurrentAllPartList(List<Structure2DNode> nodeList)
		{
			List<ColumnProfilePart> list = new List<ColumnProfilePart>();
			foreach (Structure2DNode structure2DNode in nodeList)
			{
				foreach (Structure2DPole structure2DPole in structure2DNode.PoleList)
				{
					ColumnProfilePart part = structure2DPole as ColumnProfilePart;
					int num = list.FindIndex((ColumnProfilePart s) => s.SameAs(part));
					if (num <= -1)
					{
						list.Add(part);
					}
				}
			}
			return list;
		}

		protected void AddCurveToProfile(XYZ ptStart, XYZ ptEnd, double bugle, ref List<Curve> profile)
		{
			try
			{
				Curve curve = this.GetCurve(ptStart, ptEnd, bugle);
				profile.Add(curve);
			}
			catch (Exception)
			{
			}
		}

		protected XYZ m_SelecetBoxMin;

		protected XYZ m_SelecetBoxMax;

		protected Dictionary<XYZ, bool> m_dicUsePointTag;
	}
}
